package com.yituo.mjworld.core.web.servlet;


import com.yituo.mjworld.core.utils.ApplicationContextHolder;
import com.yituo.mjworld.core.web.core.MyHttpRequest;
import com.yituo.mjworld.core.web.core.MyHttpResponse;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 控制访问的总servlet
 * 负责拦截所有访问api的url
 * 该类主要功能负责拦截访问该类的所有请求,并分发处理和权限拦截
 *
 * @author Administrator
 */
public class ActionController extends HttpServlet {
  private static final long serialVersionUID = 1L;

  @Override
  protected void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    requestHandler((MyHttpRequest) request, (MyHttpResponse) response);
  }

  @Override
  protected void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    requestHandler((MyHttpRequest) request, (MyHttpResponse) response);
  }

  @Override
  public void init() throws ServletException {
    super.init();
  }

  /**
   * 请求处理函数
   * 接口格式:// http://ip:port/api(servlet名称)/action(要访问的action类名)/method(要访问的方法)
   *
   * @param request
   * @param response
   * @throws ServletException
   * @throws IOException
   */
  private void requestHandler(MyHttpRequest request, MyHttpResponse response)
      throws ServletException, IOException {
    if (request.getStatus() != 200) {
      response.failedForfilter(request);
      return;
    }
    dispatch(request, response);
  }

  /**
   * 分发Action
   *
   * @param req
   * @param res
   * @throws SecurityException
   * @throws NoSuchMethodException
   * @throws InvocationTargetException
   * @throws IllegalArgumentException
   * @throws IllegalAccessException
   */
  public void dispatch(MyHttpRequest req, MyHttpResponse res) throws IOException {
    try {
      String actionName = req.getActionName();
      actionName = actionName + "Action";
      Object bean = ApplicationContextHolder.getBean(actionName);
      Class clazz = bean.getClass();
      Method method = null;
      method = clazz.getMethod(req.getMethodName(), MyHttpRequest.class, MyHttpResponse.class);
      method.invoke(bean, req, res);
    } catch (NoSuchMethodException e) {
      // 无匹配接口
      res.failedFor404("接口未找到");
    } catch (IllegalAccessException e) {
      // 访问了私有方法
      res.failedFor404("你没有权限访问该方法!");
    } catch (InvocationTargetException e) {
      res.failedFor404("服务器错误,请联系服务器管理人员进行检查.");
      // 后台接口执行错误
    }
    return;
  }
}
